import processing.core.PApplet;
import toxi.geom.*;

/**
 * A Curve is a drawn stage object which is essentially a vector object because we keep track of
 * all of its points.  In object mode it should be possible to manipulate and modify the drawing.
 * It is assigned a cursor to help the main program account for the fact that there may be several
 * curves being drawn simultaneously.
 * 
 */
public class Curve {
  private PApplet parent;
  private Vec3D[] points;
  private float[] widths;
  private int type = 0;
  private int pts = 0;
  private int cursor; // Cursor ID
  private boolean finished; //if is finished, no more pushing
  
  public Curve(PApplet p, Vec3D v, int curID) {

    parent = p;
    points = new Vec3D[5000];
    widths = new float[5000];
    push(v,0);
    cursor = curID;
    finished = false;
    
  }
  
  public Curve(PApplet p, String encodedCurve) {
    parent = p;
    points = new Vec3D[5000];
    widths = new float[5000];
    int tempPts = 0;
    
    PApplet.println("inside of curve creation");
    
    String[] tmpCurve = parent.split(encodedCurve, ' ');
    String[] basicElements = parent.split(tmpCurve[0], '/');
    
    if(!basicElements[1].equalsIgnoreCase("curve")) {
      parent.println("There was an error loading the curve.  Malformatted String.");
      return;
    } else {
      type = new Integer(basicElements[2]).intValue();
      finished = new Boolean(basicElements[3]).booleanValue();
      cursor = new Integer(basicElements[4]).intValue();
      tempPts = new Integer(basicElements[5]).intValue();
      PApplet.println("The curve's header is: " + type + ", " + finished + ", " + cursor + ", " + pts);
    }
    
    
    for(int i = 1; i < tempPts; i++) {
      
      String[] pointInfo = parent.split(tmpCurve[i], '/');
      
      int val = new Integer(pointInfo[0]).intValue();
      
      float tx = (new Float(pointInfo[1])).floatValue();
      float ty = (new Float(pointInfo[2])).floatValue();
      float wid = (new Float(pointInfo[3])).floatValue();
      PApplet.println("Inside vertex loop: " + val + " , "+ tx + " , " + ty + " , " + wid);
      
      push(new Vec3D(tx, ty, 0),wid);
    }
    
    PApplet.println("Finished Loading Curve.");
  }
  
  public void push(Vec3D v,float w) {
    points[pts] = v;
    widths[pts] = w;
    pts++;
    //System.err.println(pts);
  }
  
  public void print() {
    for (int i = 0; i< points.length; i++) {
        System.err.println(i +  " , " + points[i]);
    }
  }
  
  public void draw() {
    if (type == 0) { calligraphy(); }
    else {
      //need to add in other draw types
    }
  }
  
  public int getCursor() {
    return cursor;
  }
  
  public void setFinished() {
    finished = true;
  }
  
  public boolean isFinished() {
    return finished;
  }
  
  public void setType( int t) {
    type = t; 
  }
  
  /** Drawing Types **/
  
  private void calligraphy() {
    
    if (pts > 1) {
      //parent.fill(255,155,255,240);
      parent.fill(0);
      parent.beginShape(parent.TRIANGLE_STRIP);
      
      //draw first vertex
      float px = points[0].x;
      float py = points[0].y;
      float fx = px;
      float fy = py;

      parent.vertex(fx,fy);//,fz);
      
      for(int i = 1; i < pts; i++) {
        float dx = points[i].x;
        float dy = points[i].y;
        parent.vertex( dx - widths[i] / 2, dy + widths[i] / 2); //, dx);//, dy);//, abs((fx + dx) / 2), abs((fy + dy) / 2)); //, abs((fz + dz) / 2) ); //not sure if this anchor point is correct
        parent.vertex( dx + widths[i] /2, dy - widths[i] / 2);
        //fx = dx;
        //fy = dy;

      }
      
      parent.endShape();
    }
    
  }
  
  public String toString() {
    String tmp = null;
    tmp = "/curve/" + type + "/" + finished + "/" + cursor + "/" + pts;
    for(int i = 1; i < pts; i++) {
      tmp = tmp + " " + i + "/" + points[i].x + "/" + points[i].y + "/" + widths[i];
    }
    return tmp;
  }
  
}
